Le nouveau rideau de fer
Un exemple de carte en 2.5D
Introduction
Ce document montre comment réaliser cette carte de discontuités en 2,5D (fausse 3D) joliement mise en page entrièrement dans le langage R. Des versions antérieures de cette carte ont déjà été publiées par le passé, dans le manuel de cartographie (Lambert, Zanin 2016), ou dans Mad Maps (Lambert, Zanin 2019) et ont fait l’objet de billets de blog (Lambert 2017). Ici, nous entendons prouver qu’il est possible de réaliser ce type de carte sans passer par un logiciel DAO (Lambert 2019). Les sources et les références sont précisées à la fin du document.
library("sf")
library("mapsf")
library("eurostat")
library("rnaturalearth")1 Préparation des données
Pour réaliser cette carte, nous utilisons pour cela les packages eurostat (Lahti et al. 2017), RnaturalEarth (South 2017), sf (Pebesma 2018) et mapsf (mapsf?).
1.1 Fond de carte
Avec le package Eurostat, nous créons d’un fond de carte hybride avec maillage homogène nuts2/3. Tous les les pays sont au niveau nuts3 version 2016 sauf l’Autriche, la Belgique, la Suisse, l’Allemagne, la Grèce, les Pays-Bas, la Turquie, l’Irlande, l’Islande et la Norvège. Pour des raisons de disponibilité des données post Brexit, Le Royaume-Uni est au niveau nuts2 vesrion 2013.
nuts2016 <- get_eurostat_geospatial(
output_class = "sf",
resolution = "20",
nuts_level = "all",
year = "2016"
)
nuts2016_3 <- nuts2016[nuts2016$LEVL_CODE == 3, ]
nuts2016_2 <- nuts2016[nuts2016$LEVL_CODE == 2, ]
N2 <-
c("AT", "BE", "CH", "DE", "EL", "NL", "UK", "TR", "IE", "IS", "NO")
nuts <- rbind(nuts2016_2[nuts2016_2$CNTR_CODE %in% N2, ],
nuts2016_3[!nuts2016_3$CNTR_CODE %in% N2, ])
nuts <- nuts[nuts$CNTR_CODE != "UK", ]
nuts <- nuts[,c("id","NUTS_NAME","geometry")]
colnames(nuts) <- c("id","name","geometry")
nuts2013 <- get_eurostat_geospatial(
output_class = "sf",
resolution = "20",
nuts_level = "2",
year = "2013"
)
uk = nuts2013[nuts2013$CNTR_CODE == "UK",c("id","NUTS_NAME","geometry")]
colnames(uk) <- c("id","name","geometry")
nuts <- rbind(nuts, uk)
nuts <-
nuts[!nuts$id %in% c("FRY10", "FRY20", "FRY30", "FRY40", "FRY50"), ]
nuts <- nuts[nuts$id != "RS", ]1.2 Données statistiques
Import des données statistiques (PIB par habitant en euros zn 2016)
var <- "nama_10r_3gdp"
gdpinh <- get_eurostat(var, time_format = "num")
gdpinh <- subset(gdpinh, gdpinh$unit == "EUR_HAB")
gdpinh <- reshape2::dcast(gdpinh, geo ~ time, value.var = "values")
fields <- c("geo", "2016")
gdpinh <- gdpinh[, fields]
colnames(gdpinh) <- c("id","GDPINH_2016")A Cause du Brexit, les données pour le Royaume-Uni ne sont plus disponibles. On va les chercher dans dans le fichier missing.csv issu de la base de données ESPON.
missing <- read.csv("data/missing.csv")
gdpinh = rbind(gdpinh, missing)Pour des questions de reproductibilité, nous sauvegardons les données dans le répertoire data.
write.csv(gdpinh, "data/gdpinh.csv")Jointure des données et du fond de carte
nuts <- merge(
x = nuts,
y = gdpinh,
by = "id",
all.x = TRUE
)1.3 Couches d’habillage
Import des couches d’habillage avec le package RnaturalEarth
land <- ne_download(
scale = 110,
type = "land",
category = "physical",
returnclass = "sf"
)mf_map(land, border = NA, col = "#6eb1db")ocean <- ne_download(
scale = 110,
type = "ocean",
category = "physical",
returnclass = "sf"
)mf_map(ocean, border = NA, col = "#6eb1db")Graticule avec sf
graticule = st_graticule(
crs = st_crs(4326),
ndiscr = 100,
lon = seq(-180, 180, by = 2),
lat = seq(-90, 90, by = 1),
margin = 0.01
)mf_map(graticule, col = "#6eb1db")Mise en forme des couches
1.4 Template cartographique
Pour donner un effet de rotondité et permettre une représentation en 2.5D, on opte pour une projection orthographique centré sur l’Afrique. Pour éviter tout problème dans l’opération de projection (bug, artefacts, etc.), nous definissons au préalable un rectangle nous servant à découper les différentes couches.
NB : passer sf_use_s2 à FALSE permet de faire comme si il ne s’agissait pas de coordonnées sur le globe.
bb <-
st_as_sfc(st_bbox(c(
xmin = -50 ,
xmax = 70,
ymin = 20,
ymax = 80
),
crs = st_crs(4326)))
sf::sf_use_s2(FALSE)
ocean <- st_intersection(ocean, bb)
ocean <- st_segmentize(ocean, 100)
land <- st_intersection(land, bb)
land <- st_segmentize(land, 100)
graticule <- st_intersection(graticule, bb)
sf::sf_use_s2(TRUE)Projection
ortho <- "+proj=ortho +lat_0=-10 +lon_0=15 +x_0=0 +y_0=0
+ellps=WGS84 +units=m +no_defs"
ocean <- st_transform(ocean, ortho)
land <- st_transform(land, ortho)
graticule = st_transform(graticule, ortho)
nuts <- st_transform(nuts, ortho)Affichages des couches recadrées et projetées
par(mar = c(0, 0, 0, 0), mfrow = c(2, 2))
mf_map(land, col = "#6eb1db", border = NA)
mf_title("land", bg = "#6eb1db")
mf_map(ocean, col = "#6eb1db", border = NA)
mf_title("ocean", bg = "#6eb1db")
mf_map(graticule, col = "#6eb1db", lwd = 1)
mf_title("graticule", bg = "#6eb1db")
mf_map(nuts,
col = "#6eb1db",
border = "white",
lwd = 0.2)
mf_title("nuts", bg = "#6eb1db")dev.off()null device
1
On peut générer un effet d’ombrage en unissant les régions nuts et en effectuant des déplacements successifs avec de la transparence. Voir l’exemple ci-dessous sur la France.
fr <- st_union(nuts[substr(nuts$id, 1, 2) == "FR", ])
par(mar = c(0, 0, 0, 0))
mf_map(fr + c(5000,-5000), col = "#827e6c40", border = NA)
mf_map(fr + c(10000,-10000),
col = "#827e6c40",
border = NA,
add = TRUE)
mf_map(fr + c(15000,-15000),
col = "#827e6c40",
border = NA,
add = TRUE)
mf_map(fr + c(20000,-20000),
col = "#827e6c40",
border = NA,
add = TRUE)
mf_map(fr + c(25000,-25000),
col = "#827e6c40",
border = NA,
add = TRUE)
mf_map(
fr,
col = "#6eb1db",
border = "white",
lwd = 0.1,
add = TRUE
)1.5 Template
Réalisation du template cartographique. Pour bien maîtriser le format de l’image, nous utilisons la fonction getFigDim et nous générons la carte au format png en définissant précisément l’emprise de la carte. Ici, les cartes sont crées au format png et enregistrées dans le répertoire figures/.
k <- 100000
extent <- c(-20, 42, 24.5, 63) * k
bb <- st_as_sfc(st_bbox(
c(
xmin = extent[1],
xmax = extent[3],
ymin = extent[2],
ymax = extent[4]
),
crs = st_crs(nuts)
))On crée une fonction template()
template = function(file){
theme <- mf_theme(
x = "default",
bg = "#f2efe6",
fg = "#f2efe6",
mar = c(0, 0, 0, 0),
tab = TRUE,
pos = "left",
inner = FALSE,
line = 2,
cex = 1.9,
font = 3
)
mf_export(
bb,
export = "png",
width = 2000,
filename = file,
res = 150,
theme = theme,
expandBB = c(-.02, 0, 0.05, 0)
)
mf_map(ocean,
col = "#9acbe3",
border = "#9acbe3",
lwd = 5,
add = TRUE)
mf_map(
graticule,
col = "#FFFFFF80",
lwd = 1.5,
lty = 3,
add = TRUE
)
ue <- st_union(nuts)
mf_map(ue + c(5000,-5000),
col = "#827e6c40",
border = NA,
add = TRUE)
mf_map(ue + c(10000,-10000),
col = "#827e6c40",
border = NA,
add = TRUE)
mf_map(ue + c(15000,-15000),
col = "#827e6c40",
border = NA,
add = TRUE)
mf_map(ue + c(20000,-20000),
col = "#827e6c40",
border = NA,
add = TRUE)
mf_map(ue + c(25000,-25000),
col = "#827e6c40",
border = NA,
add = TRUE)
mf_map(
nuts,
col = "#f0aa0c",
border = "white",
lwd = 0.3,
add = TRUE
)
}Et voilà le résultat :-)
template("figures/fig1.png")
dev.off() # Carte choroplèthe
1.6 Choix des classes et des couleurs
# Discrétisation
bks <-
mf_get_breaks(x = nuts$GDPINH_2016,
nbreaks = 6,
breaks = "quantile")
# Couleurs
cols <-
c("#50b160",
"#98c17e",
"#cce3c4",
"#fbf5bd",
"#fcc34f",
"#e97d40")1.7 Réalisation de la carte
template("figures/fig2.png")
mf_map(
x = nuts,
var = "GDPINH_2016",
type = "choro",
breaks = bks,
pal = cols,
lwd = 0.2,
leg_pos = "n",
add = TRUE
)
mf_legend(
type = "choro",
pos = c(11 * k, 58.8 * k),
title = "",
val = bks,
val_cex = 0.5,
pal = cols,
cex = 0.85,
border = "red",
val_rnd = 0,
no_data = FALSE,
frame = FALSE
)
text(
10.5 * k,
y = 59.1 * k,
"Gross Domestic Product",
cex = 0.75,
pos = 4,
font = 2,
col = "#404040"
)
text(
10.5 * k,
y = 58.7 * k,
"(in € per inh. in 2016)",
cex = 0.55,
pos = 4,
font = 1,
col = "#404040"
)
dev.off()png
2
FIX PB LEGEND !
2 Discontinuités
todo…
3 Extrusion
todo…
4 Résultat
todo…
Bibliographie
Annexes
Info session
| setting | value |
|---|---|
| version | R version 4.0.3 (2020-10-10) |
| os | Ubuntu 20.04.3 LTS |
| system | x86_64, linux-gnu |
| ui | X11 |
| language | (EN) |
| collate | en_US.UTF-8 |
| ctype | en_US.UTF-8 |
| tz | Europe/Paris |
| date | 2021-10-15 |
| package | ondiskversion | source |
|---|---|---|
| eurostat | 3.7.5 | CRAN (R 4.0.3) |
| mapsf | 0.3.0 | CRAN (R 4.0.3) |
| rnaturalearth | 0.1.0 | CRAN (R 4.0.3) |
| sf | 1.0.3 | CRAN (R 4.0.3) |
Citation
Nicolas LAMBERT (2021). “Le nouveau rideau de fer.” <URL:, https://neocarto.github.io/ironcurtain/>.
Format BibTex :
@misc{,
title={Le nouveau rideau de fer},
url={https://neocarto.github.io/ironcurtain/},
journal={Rzine.fr},
publisher={FR CIST},
author={{Nicolas LAMBERT}},
year={2021},
month={10}
}